package sample.Shapes;

import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import sample.Utils.IsInUtils;
import sample.Utils.RedrawUtils;
import sample.Utils.SplitShapArray;

import java.util.List;
import java.util.Random;

public class ArrowLine {
    public Canvas canvas;
    public GraphicsContext gc;
    public List<Object> totalList;
    List<ArrowLine> arrowLines;
    List<Circle> circles;
    List<Ellipse> ellipses;

    public double lineStartX, lineStartY; // 线的起点
    public double lineEndX, lineEndY;     // 线的终点
    public int draggingEndpoint = -1; // 当前正在拖动的线端点（0: 起点，1: 终点，-1: 无）
    public int id;

    public ArrowLine(GraphicsContext gc, Canvas canvas, double lineStartX, double lineStartY, double lineEndX, double lineEndY) {
        this.lineEndX = lineEndX;
        this.lineEndY = lineEndY;
        this.lineStartX = lineStartX;
        this.lineStartY = lineStartY;

        this.canvas = canvas;
        this.gc = gc;
        this.id=new Random().nextInt(10000);

        registerMouseEvents(canvas, gc);

        draw(gc,lineStartX,lineStartY,lineEndX,lineEndY);
    }

    public void setTotalList(List<Object> totalList){
        this.totalList=totalList;

        arrowLines= SplitShapArray.getArrowLines(totalList);
        circles= SplitShapArray.getCircles(totalList);
        ellipses=SplitShapArray.getEllipses(totalList);
    }

    // 注册鼠标事件处理器
    private void registerMouseEvents(Canvas canvas, GraphicsContext gc) {
        canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, this::handleMousePressed); // 鼠标按下事件
        canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, e -> handleMouseDragged(e, gc)); // 鼠标拖动事件
        canvas.addEventHandler(MouseEvent.MOUSE_RELEASED, e -> {
            draggingEndpoint = -1;
        });
    }

    // 处理鼠标按下事件
    private void handleMousePressed(MouseEvent event) {
        double mouseX = event.getX(); // 获取鼠标点击位置
        double mouseY = event.getY();

        if (IsInUtils.isPointInLine(mouseX, mouseY,lineStartX,lineStartY,lineEndX,lineEndY)) {
            // 判断点击的是线的起点还是终点
            draggingEndpoint = (Math.hypot(mouseX - lineStartX, mouseY - lineStartY) <=
                    Math.hypot(mouseX - lineEndX, mouseY - lineEndY)) ? 0 : 1;
        }
    }

    // 处理鼠标拖动事件
    private void handleMouseDragged(MouseEvent event, GraphicsContext gc) {
        double mouseX = event.getX(); // 获取鼠标点击位置
        double mouseY = event.getY();

        if (draggingEndpoint != -1) {
            if (draggingEndpoint == 0) {
                lineStartX = mouseX; // 更新起点
                lineStartY = mouseY;

                if(circles!=null){
                    for (Circle circle:circles){
                        if(IsInUtils.isPointInCircle(lineStartX,lineStartY,circle.x,circle.y,circle.w,circle.h)){
                            lineStartX = circle.x+circle.CIRCLE_SIZE/2; // 更新起点
                            lineStartY = circle.y+circle.CIRCLE_SIZE/2;
                        }
                    }
                }

                if(ellipses!=null){
                    for (Ellipse ellipse:ellipses){
                        if(IsInUtils.isPointInCircle(lineStartX,lineStartY,ellipse.x,ellipse.y,ellipse.w,ellipse.h)){
                            lineStartX = ellipse.x+ellipse.w/2; // 更新起点
                            lineStartY = ellipse.y+ellipse.h/2;
                        }
                    }
                }
            }

            if (draggingEndpoint == 1) {
                lineEndX = mouseX;   // 更新终点
                lineEndY = mouseY;

                if(circles!=null){
                    for (Circle circle:circles){
                        if(IsInUtils.isPointInCircle(lineEndX,lineEndY,circle.x,circle.y,circle.w,circle.h)){
                            lineEndX = circle.x+circle.CIRCLE_SIZE/2; // 更新终点
                            lineEndY = circle.y+circle.CIRCLE_SIZE/2;
                        }
                    }
                }

                if(ellipses!=null){
                    for (Ellipse ellipse:ellipses){
                        if(IsInUtils.isPointInCircle(lineEndX,lineEndY,ellipse.x,ellipse.y,ellipse.w,ellipse.h)){
                            lineEndX = ellipse.x+ellipse.w/2; // 更新起点
                            lineEndY = ellipse.y+ellipse.h/2;
                        }
                    }
                }
            }
        }

        totalList=RedrawUtils.redraw(gc,totalList,arrowLines,circles,ellipses);
    }

    // 绘制带箭头的线段
    public void draw(GraphicsContext gc, double startX, double startY, double endX, double endY) {
        lineStartX = startX;
        lineStartY = startY;
        lineEndX = endX;
        lineEndY = endY;

        double dx = endX - startX, dy = endY - startY; // 线向量
        double length = Math.hypot(dx, dy); // 线长度
        double arrowLength = 10; // 箭头长度
        double arrowAngle = Math.toRadians(30); // 箭头角度

        double ux = dx / length, uy = dy / length; // 单位向量
        double angleSin = Math.sin(arrowAngle), angleCos = Math.cos(arrowAngle); // 角度的正弦和余弦

        // 计算箭头两个翼的向量
        double leftDx = ux * angleCos - uy * angleSin;
        double leftDy = ux * angleSin + uy * angleCos;
        double rightDx = ux * angleCos + uy * angleSin;
        double rightDy = -ux * angleSin + uy * angleCos;

        // 计算箭头尖端位置
        double arrowTipX = endX - arrowLength * ux;
        double arrowTipY = endY - arrowLength * uy;
        double leftWingX = arrowTipX - arrowLength * leftDx;
        double leftWingY = arrowTipY - arrowLength * leftDy;
        double rightWingX = arrowTipX - arrowLength * rightDx;
        double rightWingY = arrowTipY - arrowLength * rightDy;

        // 绘制线段
        gc.setStroke(Color.GREEN);
        gc.setLineWidth(2);
        gc.strokeLine(startX, startY, endX, endY);

        // 绘制箭头
        gc.setFill(Color.GREEN);
        gc.beginPath();
        gc.moveTo(endX, endY);
        gc.lineTo(leftWingX, leftWingY);
        gc.lineTo(rightWingX, rightWingY);
        gc.closePath();
        gc.fill();
    }
}
